'''
Created on Aug 23, 2010

@author: alia
'''
import logging
log = logging.getLogger('player')
log.debug("imported")
 
from pyglet.window import key

import cocos
from cocos import draw
from cocos.euclid import *
from cocos.director import director
from cocos.actions import *

import anims
from player_stats import PlayerStats
from steer import Steer
import pyglet

from force import Force
from pyknic.geometry import Vec2

log.debug("about to imporet npc")
from npc_sprite import NPCSprite
import game_audio

log.debug("imports finished")


        
class UserControlledSprite(NPCSprite, PlayerStats, Steer):
    keyboard = key.KeyStateHandler()
    def __init__(self, game, pos, speach_offset = None, collision_data =  None):
        
        frames = [
                  "images/ffly_top1.png",
                  "images/ffly_top2.png",
                  "images/ffly_top3.png",
                  "images/ffly_top2.png"
                  ]
        
        upAnim = anims.MakeAnimFromFrames(frames, 0.05)
 
        self.upSprite = cocos.sprite.Sprite(upAnim)
        downAnim = upAnim.get_transform(False, True, 0)
        self.downSprite = cocos.sprite.Sprite(downAnim)
        
        frames = [
                  "images/ffly_side1.png",
                  "images/ffly_side2.png",
                  "images/ffly_side3.png",
                  "images/ffly_side2.png"
                  ]
        lefAnim = anims.MakeAnimFromFrames(frames, 0.05)

        self.leftSprite = cocos.sprite.Sprite(lefAnim)
        rightAnim = lefAnim.get_transform(True, False, 0)
        self.rightSprite = cocos.sprite.Sprite(rightAnim)
        
        states = "WALK FLY STUCK DEAD"
        super(UserControlledSprite, self).__init__(pyglet.image.load('data/images/black.png'), pos, speach_offset, collision_data, states, "Player")
        Steer.__init__(self)
        
        self.scale = 0.5
        
        self.acceleration = Vector2(0,0)
        #self.forces = {Vector2(0,0): 0.0}
        self.velocity = Vector2(0,0)

        self.pos = Vector2(self.position[0],self.position[1])

        director.window.push_handlers(self.keyboard)
        self.debuf = None
        self.game = game
        self.mouse = None
        
        self.loc = cocos.text.Label("Loc: ")
        self.loc.x = 30
        self.loc.y = 10
        #self.add(self.loc)
        
        self.add(self.leftSprite)
        self.leftSprite.visible = False
        
        self.add(self.rightSprite)
        self.rightSprite.visible = False
        
        self.add(self.downSprite)
        self.downSprite.visible = False
        
        self.add(self.upSprite)
        self.upSprite.visible = False
        self.current_vis = self.upSprite

        
        self.schedule(self.update)
        self.reset(self.position)

        
    def dispatch_npc_event(self, evt, *args):
        if self.game is not None:
            self.game.dispatch_event(evt, *args)
        
    def reset(self, pos):
        self.position = pos 
        self.pos = Vector2(self.position[0],self.position[1])
        self.velocity = Vector2(0,0) 
        self.acceleration = Vector2(0,0)
        self.force_accumulator  = Vector2(0,0)
        game_audio.play_sound("fx_spawn.ogg")
        
    def set_visible(self, spr):
        self.current_vis.visible = False
        spr.visible = True
        self.current_vis = spr
        
    def update(self, dt):
        log.debug("update "+str(dt))

        self.pos = Vector2(self.position[0],self.position[1])

        if not self.disabled:
            self.accumulate_external_forces()
            self.position_update(dt)
        
        self.position = self.pos.x, self.pos.y

        if (self.velocity.y > 1.0) and (abs(self.velocity.y) > abs(self.velocity.x)) :
            self.set_visible(self.upSprite)            
        elif (self.velocity.y < -1.0) and (abs(self.velocity.y) > abs(self.velocity.x)) :
            self.set_visible(self.downSprite)            
        elif (self.velocity.x < -1.0) :
            self.set_visible(self.leftSprite)            
        elif (self.velocity.x > 1.0) :
            self.set_visible(self.rightSprite)            
 
        self.loc.element.text = str(self.acceleration)

    def accumulate_external_forces(self):
        loc = (self.position[0], self.position[1])        
        for force in self.forces:
            if(force.active):
                ray = (force.source[0] - loc[0], force.source[1] - loc[1])

                x1 = loc[0]
                y1 = loc[1]
                x2 = loc[0] + ray[0]
                y2 = loc[1] + ray[1]

                if(y2 < y1 ):
                    tmp = y2
                    y2 = y1
                    y1 = tmp

                if(x2 < x1):
                    tmp = x2
                    x2 = x1
                    x1 = tmp

                tiles = self.parent.get_in_region(x1, y1, x2, y2)

                if(len(tiles) > 0):
                    for tile in tiles:
                        if(tile.x != -32 and tile.y != -32):
                            return

                vec = force.get_force(loc)
                if(vec == False):
                    self.forces.remove(force)
                elif(vec is not None):
                    self.force_accumulator.x += vec[0]
                    self.force_accumulator.y += vec[1]

    def freeze(self, pos, time):
        pass


    def click(self, x, y):
        log.debug("click "+str(( x,y,director.get_virtual_coordinates (x, y))))
        
    def collide_bottom(self, dy):
        #print "collide_left",dy
        self.position = self.position[0], self.position[1]+dy
        self.velocity.y = 0

    def collide_left(self, dx):
        #print "collide_left",dx
        self.position = self.position[0]+dx, self.position[1]
        self.velocity.x = 0

    def collide_right(self, dx):
        #print "collide_right",dx
        self.position = self.position[0]+dx, self.position[1]
        self.velocity.x = 0

    def collide_top(self, dy):
        #print "collide_top",dy
        self.position = self.position[0], self.position[1]+dy
        self.velocity.y = 0

 
def run(moo):
    from mouse import MouseManager

    main_scene = cocos.layer.Layer()
    res = anims.GetFramesFromFile("images/nethackcreaturetiles32x32.png", [32,32])
    player = UserControlledSprite(main_scene, [200,200], None)
    layer = MouseManager(player, None)

    layer.add(player)
    
    main_scene.add(layer)
   
    return main_scene

if __name__ == '__main__':



    director.init(width=640, height=480, do_not_scale=True)    
    director.run(run())

